"""
TypeDefinitions.py -- some definitions to handle C++ class informations.

This module contains implementations for an object describing a C++
class, with its members, methods, constructors, ... The idea is to use
the ClassRepresentation to hold the information needed to write actual
header and part of the implementation file, reading the information
from XML file.

Todo :
=====
 * add template classes and methods.
"""

##@package TypeDefinitions
# This module contains implementations for an object describing a C++
# class, with its members, methods, constructors, ... The idea is to
# use the ClassRepresentation to hold the information needed to write
# actual header and part of the implementation file, reading the
# information from XML file.
#
# Contains the classes TypeRepresentation, ArgumentRepresentation,
# MemberRepresentation, ConstructorRepresentation,
# MethodRepresentation, ClassRepresentation and
# StructureRepresentation.
#
# @author Johan "Solo" Luisier
# @date October 2011

## This class represents what is a C++ "type": the type has a name,
# like unsigned int, string, ... The type is completed by "modifiers":
# the object can be a reference, a pointer, can be const or not.
#
# @author Johan "Solo" Luisier
# @date October 2011
class TypeRepresentation :
    ## Constructor
    #
    # Initialises the variables, the type name is set to "" and
    # all switches are set to False. 
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        ## Name of the type, i.e. "unsigned int", "std::deque< double
        # >", ...
        self.__TypeName = ""
        ## Is \e True if the type is a reference.
        self.__Reference = False
        ## Is \e True if the type is constant.
        self.__Constness = False
        ## Is \e True if the type is a pointer to something.
        self.__Pointer   = False
    ## Allows to change the value of TypeName.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] name new value of TypeName
    #
    # @return value of TypeName
    def setTypeName( self, name ) :
        self.__TypeName = name
        return self.__TypeName
    ## Allows to access TypeName.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of TypeName
    def getTypeName( self ) :
        return self.__TypeName
    ## Allows to change the Reference switch.
    #
    # @param[in] self reference of the calling instance
    # @param[in] boolean new value of Reference
    #
    # @return value of Reference
    def setReference( self, boolean ) :
        self.__Reference = boolean
        return self.__Reference
    ## Allows to access Reference switch value.
    #
    # @return value of Reference.
    def getReference( self ) :
        return self.__Reference
    ## Allows to change the value of Constness switch.
    #
    # @param[in] self reference of the calling instance.
    # @param[in] boolean new value of Constness.
    #
    # @return value of Constness.
    def setConstness( self, boolean ) :
        self.__Constness = boolean
        return self.__Constness
    ## Allows to access Constness switch value.
    #
    # @return value of Constness.
    def getConstness( self ) :
        return self.__Constness
    ## Allows to change the value of Pointer switch.
    #
    # @param[in] self reference of the calling instance.
    # @param[in] boolean new value of Pointer.
    #
    # @return value of Pointer.
    def setPointer( self, boolean ) :
        self.__Pointer = boolean
        return self.__Pointer
    ## Allows to access Pointer switch value.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Pointer.
    def getPointer( self ) :
        return self.__Pointer
    ## Allows to write the "prototype".
    # The prototype is the string used to define the type of a
    # variable, member, argument, or even the return type of a
    # function. It looks like [const] typename[*][&]
    #
    # If the variable / function / argument is a reference \e and a
    # pointer, this will be written as type*& (i.e. a reference on a
    # pointer).
    #
    # @param[in] self reference of the calling instance.
    # @param[in] header switches between header and implementation
    # line production (does not change anything in this particular
    # case).
    #
    # @return a string made of [const] typename[*][&]
    def producePrototype( self, header = True ) :
        string = str()
        if ( self.getConstness() == True ) :
            string += "const "
        string += self.getTypeName()
        if ( self.getPointer() == True ) :
            string += "*"
        if ( self.getReference() == True ) :
            string += "&"
        return string
        

## Class implementing an argument (of a function, method, ...). An
# argument has a name, and is a variable, therefore the
# ArgumentRepresentation class inherits from TypeRepresentation.
#
# @author Johan "Solo" Luisier
# @date October 2011
class ArgumentRepresentation( TypeRepresentation ) :
    ## Constructor
    # The constructor relies on TypeRepresentation.__init__
    # constructor, and initialises the Name member.
    #
    # @param[in] self reference on calling instance.
    def __init__( self ) :
        TypeRepresentation.__init__( self )
        self.__Name    = ""
        self.__Default = ""
    ## Allows to change the name of the argument.
    #
    # @param[in] self reference on calling instance.
    # @param[in] argName new value of Name.
    #
    # @return value of Name.
    def setName( self, argName ) :
        self.__Name = argName
        return self.__Name
    ## Allows to access the Name member.
    #
    # @return value of Name.
    def getName( self ) :
        return self.__Name
    ## Allows to change the default value of the argument.
    #
    # @param[in] self reference on calling instance.
    # @param[in] argDefault new value of Default.
    #
    # @return the value of __Default.
    def setDefault( self, argDefault ) :
        self.__Default = argDefault
        return self.__Default
    ## Allows to access the default value of the argument.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __Default.
    def getDefault( self ) :
        return self.__Default
    ## Allows to write the prototype.
    # The prototype is composed by two elements: the type itself and
    # the name of the argument. If it has a default value, this one is
    # added too. The produced string looks like [const] typename[*][&]
    # name [= default]. Only the name and possible default value are
    # processed here, the rest is delegated to the %TypeRepresentation
    # base class.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switches between header and implementation
    # line production.
    #
    # @return the "[const] type[*][&] name [= default]" string.
    def producePrototype( self, header = True ) :
        string = TypeRepresentation.producePrototype( self, header )
        string += " " + self.getName()
        if ( self.getDefault() != "" ) :
            string += " = " + self.getDefault()
        return string
    ## Allows to write the implementation.
    # The implementation version differs from the prototype in the way
    # that the possible default value is \e never shown.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switches between header and implementation
    # file production.
    #
    # @return the [const] type[*][&] name" string.
    def produceImplementation( self, header = False ) :
        string = TypeRepresentation.producePrototype( self )
        string += " " + self.getName()
        return string
    ## Produces the comment output.
    # The comment generated by the ArgumentRepresentation class is a
    # line starting with a "*", followed by the "\@param" doxygen
    # keyword. If the argument is a const reference, then it is
    # assumed that it is an input argument, and if it is a non const
    # refenrence, it is assumed that it is an output argument. In all
    # other cases there is no assumption. The name of the argument is
    # then appended.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the line "* \@param[] name" corresponding to the
    # argument.
    def produceComment( self ) :
        string = " * @param"
        if ( self.getReference() and self.getConstness() ) :
            string +=  "[in] "
        elif ( self.getReference() ) :
            string +=  "[out] "
        else :
            string += " "
        string += self.getName() + " \n"
        return string

## Class representing a C++ class member.
# A C++ class member has a type (thus MemberRepresentation inherits
# from TypeRepresentation) and a name. A class member is usually not
# public, therefore get/set methods are needed to access and change
# its value. A member can also be static.
#
# @author Johan "Solo" Luisier
# @date October 2011
class MemberRepresentation( TypeRepresentation ) :
    ## Constructor
    # It relies on the contructor of TypeRepresentation, and
    # initialises specific members. The name is "" and all switches
    # are set to \e False.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        TypeRepresentation.__init__( self )
        self.__Name    = ""
        self.__StdGet  = True
        self.__StdSet  = True
        self.__PtrGet  = False
        self.__PtrSet  = False
        self.__Mutable = False
        self.__Static  = False
        self.__Value   = ""
    ## Allows to change the value of Name.
    #
    # @param[in] argName new value of Name.
    #
    # @return value of Name.
    def setName( self, argName ) :
        self.__Name = argName
        return self.__Name
    ## Allows to access the value of Name.
    #
    # @return value of Name.
    def getName( self ) :
        return self.__Name
    ## Allows to change the value of the StdGet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of StdGet.
    #
    # @return value of StdGet.
    def setStdGet( self, boolean ) :
        self.__StdGet = boolean
        if ( not self.__StdGet ) :
            self.__Value = ""
        return self.__StdGet
    ## Allows to access the value of the StdGet switch
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of StdGet.
    def getStdGet( self ) :
        return self.__StdGet
    ## Allows to change the value of the StdSet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of StdSet.
    #
    # @return value of StdSet.
    def setStdSet( self, boolean ) :
        self.__StdSet = boolean
        if ( not self.__StdSet ) :
            self.__Value = ""
        return self.__StdSet
    ## Allows to access the value of the StdSet switch
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of StdSet.
    def getStdSet( self ) :
        return self.__StdSet
    ## Allows to change the value of the PtrGet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of PtrGet.
    #
    # @return value of PtrGet.
    def setPtrGet( self, boolean ) :
        self.__PtrGet = boolean
        if ( not self.__PtrGet ) :
            self.__Value = ""
        return self.__PtrGet
    ## Allows to access the value of the PtrGet switch.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of PtrGet.
    def getPtrGet( self ) :
        return self.__PtrGet
    ## Allows to change the value of the PtrSet switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of PtrSet.
    #
    # @return value of PtrSet.
    def setPtrSet( self, boolean ) :
        self.__PtrSet = boolean
        if ( not self.__PtrSet ) :
            self.Value = ""
        return self.__PtrSet
    ## Allows to access the value of the PtrSet switch.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of PtrSet.
    def getPtrSet( self ) :
        return self.__PtrSet
    ## Allows to change the value of the Mutable switch.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of Mutable.
    #
    # @return value of Mutable.
    def setMutable( self, boolean ) :
        self.__Mutable = boolean
        return self.__Mutable
    ## Allows to access the value of the Mutable switch
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Mutable.
    def getMutable( self ) :
        return self.__Mutable
    ## Allows to change the value of the Static switch.
    #
    # If the switch is set to \e False, the default value is reset to
    # "".
    #
    # @param[in] self reference on the calling instance.
    # @param[in] boolean new value of Static.
    #
    # @return value of Static.
    def setStatic( self, boolean ) :
        self.__Static = boolean
        if ( not self.__Static ) :
            self.Value = ""
        return self.__Static
    ## Allows to access the value of the Static switch.
    #
    # @return value of Static.
    def getStatic( self ) :
        return self.__Static
    ## Allows to change the default value of the member (if static).
    #
    # If the method is called, the Static switch is automatically set
    # to \e True.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] defValue new value of Value.
    #
    # @return value of Value.
    def setValue( self, defValue ) :
        self.__Static = True
        self.__Value = defValue
        return self.__Value
    ## Allows to access the value of Value.
    #
    # @return value of Value.
    def getValue( self ) :
        return self.__Value
    ## Allows to write the prototype.
    # The prototype looks like [static] [const/mutable] typename[*][&]
    # name. Actually the method here only takes care about the static
    # and mutable keywords, then adds the name and the
    # semi-column. The rest is delegated to the %TypeRepresentation
    # base class.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switches between header and implementation
    # file production.
    #
    # @return the line "[static] [const/mutable] type[*][&] name;"
    def producePrototype( self, header = True ) :
        string = str()
        if ( self.getStatic() ) :
            string += "static "
        if ( self.getMutable() ) :
            string += "mutable "
        string += TypeRepresentation.producePrototype( self, True )
        string += " " + self.getName() + ";"
        return string
    ## Allows to write the implementation.
    # The implementation is written only if the member is static. In
    # this case the first part of the line comes from the
    # %TypeRepresentation base class, then the object name should be
    # added, followed by two columns, the member name and finally its
    # value. Since the object name is not known by the member (objects
    # can have members, but not the opposite), the "{0}" string is
    # used, and it is the %ObjectRepresentation is responsible for
    # replacing this by its name.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switches between header and implementation
    # file production.
    #
    # @return the line "[const] type[*][&] {0}::name( value );" when
    # the member is static. The "{0}" will be replace by the class
    # name.
    def produceImplementation( self, header = False ) :
        string = str()
        if ( self.getStatic() ) :
            string += TypeRepresentation.producePrototype( self )
            string += "{0}::" + self.getName()
            string += "( {0} );".format( self.getValue() )
        return string
    ## Produces the comment lines.
    # The produced comment is just a blank one, where the used should
    # just write a description for the member.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an empty comment.
    def produceComment( self ) :
        return "/**\n *\n */"

## Class representing a very basic "function", it is not meant to be
# used directly, but is the mother of the Constructor and Method
# classes. The common part between these two categories are the name
# and a list of arguments.
#
# @author Johan "Solo" Luisier
# @date October 2011
class _FBaseRepresentation :
    ## Constructor
    # Initialises the name (to an empty string) and the argument list
    # (to an empty array).
    #
    # @param[in] self reference on the calling instance
    def __init__( self ) :
        self.__Name = ""
        self.__ArgList = []
        self.__FunctionConstness = False
        self.__Body = ""
        self.__Comments = ""
        self.__Static      = False
        self.__Virtual     = False
        self.__PureVirtual = False
        self.__TemplateParameters = []
    ## Allows to change the name of the function.
    #
    # @param[in] self reference on calling instance.
    # @param[in] fName new value of Name.
    #
    # @return value of Name.
    def setName( self, fName ) :
        self.__Name = fName
        return self.__Name
    ## Allows to access the name of the function.
    #
    # @return value of Name.
    def getName( self ) :
        return self.__Name
    ## Allows to add an argument to the argument list.
    #
    # @param[in] self reference on calling instance.
    # @param[in] arg instance of argument to be added.
    #
    # @return nbr of arguments.
    def addArgument( self, arg ) :
        self.__ArgList.append( arg )
        return len( self.__ArgList )
    ## Allows to access the list of arguments.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the list of arguments.
    def getArguments( self ) :
        return self.__ArgList
    ## Allows to change the "function constness", i.e. the fact that
    # the given method does not change the object.
    #
    # @param[in] self reference on calling instance.
    # @param[in] functionConstness new value of __FunctionConstness.
    #
    # @return the value of __FunctionConstness.
    def setFunctionConstness( self, functionConstness ) :
        self.__FunctionConstness = functionConstness
        return self.__FunctionConstness
    ## Allows to access the "function constness".
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __FunctionConstness.
    def getFunctionConstness( self ) :
        return self.__FunctionConstness
    ## Allows to change the function body.
    #
    # @param[in] self reference on calling instance.
    # @param[in] body new value of __Body.
    #
    # @return the value of __Body.
    def setBody( self, body ) :
        self.__Body = body
        return self.__Body
    ## Allows to access the body of the function.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __Body.
    def getBody( self ) :
        return self.__Body
    ## Allows to change the function comments.
    #
    # @param[in] self reference on calling instance.
    # @param[in] comments new value of __Comments.
    #
    # @return the value of __Comments.
    def setComments( self, comments ) :
        self.__Comments = comments
        return self.__Comments
    ## Allows to access the comments of the function.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the value of __Comments.
    def getComments( self ) :
        return self.__Comments
    ## Allows to change the value of the Static switch.
    #
    # @param[in] boolean new value of Static.
    #
    # @return value of Static.
    def setStatic( self, boolean ) :
        self.__Static = boolean
        return self.__Static
    ## Allows to access the value of the Static switch
    #
    # @return value of Static.
    def getStatic( self ) :
        return self.__Static
    ## Allows to change the value of the Virtual switch.
    #
    # @param[in] boolean new value of Virtual.
    #
    # @return value of Virtual.
    def setVirtual( self, boolean ) :
        self.__Virtual = boolean
        return self.__Virtual
    ## Allows to access the value of the Virtual switch.
    #
    # @return value of Virtual.
    def getVirtual( self ) :
        return self.__Virtual
    ## Allows to change the value of the PureVirtual switch.
    # If the PureVirtual switch is set to \e True, then the Virtual
    # switch is set to \e True as well, for consistency.
    #
    # @param[in] boolean new value of PureVirtual.
    #
    # @return value of PureVirtual.
    def setPureVirtual( self, boolean ) :
        self.__PureVirtual = boolean
        if ( self.__PureVirtual ) :
            self.__Virtual = True
        return self.__PureVirtual
    ## Allows to access the value of the PureVirtual switch.
    #
    # @return value of PureVirtual.
    def getPureVirtual( self ) :
        return self.__PureVirtual
    ## Allows to access the list of template parameters.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the list of template parameters.
    def getTemplateParameters( self ) :
        return self.__TemplateParameters
    ## Allows to add a template parameter to the template parameter
    # list.
    #
    # @param[in] self reference on calling instance.
    # @param[in] template template parameter to be added.
    #
    # @return nbr of template parameters.
    def addTemplateParameter( self, keyword, template ) :
        self.__TemplateParameters.append( [ keyword, template ] )
        return len( self.__TemplateParameters )
    ## Allows to know whether the method is a template or not.
    #
    # @param[in] self reference on calling instance.
    #
    # @return \e True if the method is a template.
    def isTemplate( self ) :
        return ( len( self.__TemplateParameters ) > 0 )
    ## Builds the line template< ... > if the function is a template
    # function.
    #
    # @param[in] self reference on calling instance.
    #
    # @return an empty line for a "regular" function, or "template<
    # ... >" for a template one.
    def getTemplateDeclaration( self ) :
        if ( not self.isTemplate() ) :
            return str()
        else :
            string = "template< "
            for param in self.getTemplateParameters() :
                string += param[ 0 ] + " " + param[ 1 ] + ", "
            string = string[:-2]
            string += " >\n"
            return string
    ## Allows to write the prototype of the function.
    # In here only the function name, the arguments and the function
    # constness are handled. The rest is delegated to the specialised
    # subclasses.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switches between header and implementation
    # file production.
    #
    # @return the line "name( args ) [const]".
    def producePrototype( self, header = True ) :
        string = self.getName()
        if ( len( self.getArguments() ) > 0 ) :
            string += "( "
            for arg in self.getArguments() :
                string += arg.producePrototype( header )
                string += ", "
            string = string[:-2]
            string += " )"
        else :
            string += "()"
        if ( self.getFunctionConstness() ) :
            string += " const"
        return string
    ## Allows to write the implementation.
    # As for producePrototype method, only part of the information is
    # treated here. The produced line contains the method name, to
    # which a "{1}::" string is prepended. The latter string will be
    # replaced by the object name (under the object
    # responsibility). After the method name are printed the arguments
    # and the "const" if needed.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switches between header and implementation
    # line production.
    #
    # @return the line "{1}::name( args ) [const]".
    def produceImplementation( self, header = False ) :
        string = "{1}::"
        string += self.getName()
        if ( len( self.getArguments() ) > 0 ) :
            string += "( "
            for arg in self.getArguments() :
                string += arg.produceImplementation( header )
                string += ", "
            string = string[:-2]
            string += " )"
        else :
            string += "()"
        if ( self.getFunctionConstness() ) :
            string += " const"
        return string

## Class representing a constructor, a constructor is a function which
# has no return type. It is actually just an alias for the
# _FBaseRepresentation class.
#
# This type is also used to represent the destructor, since a
# destructor is a method without any return type.
#
# @author Johan "Solo" Luisier
# @date October 2011
class ConstructorRepresentation( _FBaseRepresentation ) :
    ## Constructor
    # Initialises the base class.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        _FBaseRepresentation.__init__( self )
    ## Allows to print the prototype.
    # The _FBaseRepresentation base class provides the possibly needed
    # template declaration line and the name of the constructor and
    # its arguments.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switch between header (\e True) or
    # implementation file (\e False) production.
    #
    # @return the name of the constructor, followed by its aguments.
    def producePrototype( self, header = True ) :
        string = self.getTemplateDeclaration()
        if ( self.getVirtual() ) :
            string += "virtual "
        string += _FBaseRepresentation.producePrototype( self, header )
        string += ";"
        return string
    ## Allows to print the implementation.
    # Produces the line for the constructor implementation. In case
    # the constructor has a template parameter (which is \e not
    # "inherited" from the object) and the line is written in the
    # implementation file, then a blank line is returned. The line
    # begins with "{0}", which will be replaced by the object template
    # parameters (if any, otherwise will be replaced by an empty
    # string), then the rest is coming from the %_FBaseRepresentation.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switch between header (\e True) or
    # implementation file (\e False) production.
    #
    # @return the name of the constructor, followed by its aguments.
    def produceImplementation( self, header = False ) :
        if ( _FBaseRepresentation.isTemplate( self ) and not header ) :
            return str( "" )
        string = "{0}"
        string += self.getTemplateDeclaration()
        string += _FBaseRepresentation.produceImplementation( self, header )
        return string
    ## Produces the comments.
    # If some custom comments were set before, then they are returned
    # by the function. If not, then a blank comment is returned,
    # containing a "{0}" on the first line, which will be replaced by
    # "constructor", "destructor", etc. Note that these words will be
    # translated before the writing.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the comments.
    def produceComment( self ) :
        if ( self.getComments() != "" ) : return self.getComments()
        string = "/** {0}\n *\n *\n"
        if ( len( self.getArguments() ) > 0 ) :
            for arg in self.getArguments() :
                string += arg.produceComment()
        string += " */"
        return string;

## Class representing a method : a method is a function with a type
# (its return type). This is why it inherits from both
# _FBaseRepresentation and TypeRepresentation.
#
# @author Johan "Solo" Luisier
# @date October 2011
class MethodRepresentation( _FBaseRepresentation, TypeRepresentation ) :
    ## Constructor
    # Initialises the two mother classes.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        _FBaseRepresentation.__init__( self )
        TypeRepresentation.__init__( self )
    ## Allows to produce the prototype.
    # First a test is made to know whether the method is a pure
    # virtual one: in this case a blank line is returned. Then the
    # line contains virtual or static if needed, followed by the
    # return type (handled by %TypRepresentation) and the name and
    # argument (handled by %_FBaseRepresentation). In case the method
    # is pure virtual, a "= 0" is appended. If the method has some
    # template parameters, they are added as a first line.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switch between header (\e True) or
    # implementation file (\e False) production.
    #
    # @return the "[static/virtual] [const] typename[*][&] name( args
    # ) [const] [= 0];" line
    def producePrototype( self, header = True ) :
        string = str()
        if ( self.getPureVirtual() ) :
            return string
        string += self.getTemplateDeclaration()
        if ( self.getStatic() ) :
            string += "static "
        if ( self.getVirtual() ) :
            string += "virtual "
        string += TypeRepresentation.producePrototype( self, header ) + " "
        string += _FBaseRepresentation.producePrototype( self, header )
        if ( self.getPureVirtual() ) :
            string += " = 0"
        string += ";"
        return string
    ## Allows to print the implementation.
    # Produces the line for the method implementation. In case the
    # method has a template parameter (which is \e not "inherited"
    # from the object) and the line is written in the implementation
    # file, then a blank line is returned. The line begins with "{0}",
    # which will be replaced by the object template parameters (if
    # any, otherwise will be replaced by an empty string), then the
    # rest is coming from %TypeRepresentation and
    # %_FBaseRepresentation. If the method is pure virtual, of course
    # an empty line is returned.
    #
    # @param[in] self reference on calling instance.
    # @param[in] header switch between header (\e True) or
    # implementation file (\e False) production.
    #
    # @return a string containing the return type, the method name and
    # arguments.
    def produceImplementation( self, header = False ) :
        if ( self.getPureVirtual() ) :
            return str( "" )
        string = "{0}"
        if ( _FBaseRepresentation.isTemplate( self ) and not header ) :
            return string
        string += self.getTemplateDeclaration()
        string += TypeRepresentation.producePrototype( self, header ) + " "
        string += _FBaseRepresentation.produceImplementation( self, header )
        return string
    ## Produces the comments.
    # If some custom comments were set before, then they are returned
    # by the function. If not, then a blank comment is returned,
    # containing one line per argument and a "* \@return " line in
    # case there is a non-void return type.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the comments.
    def produceComment( self ) :
        if ( self.getComments() != "" ) : return self.getComments()
        string = "/**\n *\n *\n"
        if ( len( self.getArguments() ) > 0 ) :
            for arg in self.getArguments() :
                string += arg.produceComment()
        if ( TypeRepresentation.getTypeName( self ) != "void" ) :
            string += " *\n * @return \n"
        string += " */"
        return string

## Class representing a basic C++ object, which can be either a class
# or a structure. A C++ object is defined by its name, the namespace
# it belongs to, a list of constructors, methods and
# members. Additional information are also provided, like the name of
# the author and the date of creation.
#
# @author Johan "Solo" Luisier
# @date February 2012
class _ObjectBaseRepresentation :
    ## Constructor
    # Initialises the members. All names are set to an empty string
    # and the lists are set to empty arrays.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        self.__ObjectType = ""
        self.__ObjectName = ""
        self.__Namespace = ""
        self.__Authors   = []
        self.__Date      = ""
        self.__Inherits  = []
        self.__PublicConstr = []
        self.__PublicMethod = []
        self.__PublicMember = []
        self.__ProtectedConstr = []
        self.__ProtectedMethod = []
        self.__ProtectedMember = []
        self.__PrivateConstr = []
        self.__PrivateMethod = []
        self.__PrivateMember = []
        self.__ForwardDeclaration = []
        self.__LocalHeaderIncludes = []
        self.__DistantHeaderIncludes = []
        self.__LocalImplementationIncludes = []
        self.__DistantImplementationIncludes = []
        self.__HeaderUsingNamespace = []
        self.__ImplementationUsingNamespace = []
        self.__AutomaticMethods = {}
        self.__TemplateMethods = []
        self.__TemplateParameters = []
    ## Allows to change the object type (i.e. either class or struct).
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the value of __ObjectType
    def setObjectType( self, objectType ) :
        self.__ObjectType = objectType
        return self.__ObjectType
    ## Allows to access the object type (i.e. either class or struct).
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the value of __ObjectType
    def getObjectType( self ) :
        return self.__ObjectType
    ## Allows to change the name of the object.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] objectName new value of ObjectName.
    #
    # @return value of Objectname.
    def setObjectName( self, objectName ) :
        self.__ObjectName = objectName;
        return self.__ObjectName
    ## Allows to get the value of the object name.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of ObjectName
    def getObjectName( self ) :
        return self.__ObjectName
    ## Allows to change the namespace of the class.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] namespace new value of Namespace.
    #
    # @return value of Namespace.
    def setNamespace( self, namespace ) :
        self.__Namespace = namespace;
        return self.__Namespace
    ## Allows to get the value of the class namespace.
    #
    # @return value of Namespace.
    def getNamespace( self ) :
        return self.__Namespace
    ## Allows to add an author.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] author new value of Author.
    #
    # @return number of authors.
    def addAuthor( self, author ) :
        self.__Authors.append( author )
        return len( self.__Authors )
    ## Allows to access the name of the author.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Author.
    def getAuthors( self ) :
        return self.__Authors
    ## Allows to change the creation date.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] date new value of Date.
    #
    # @return value of Date.
    def setDate( self, date ) :
        self.__Date = date
        return self.__Date
    ## Allows to access the creation date.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return value of Date
    def getDate( self ) :
        return self.__Date
    ## Allows to add an inheritance relation.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] name name of the mother class.
    # @param[in] access access type.
    # @param[in] virtual virtual inheritance switch, is "" if the
    # inheritance is standard, or "virtual" if the inheritance is
    # virtual.
    #
    # @return number of inheritance relations.
    def addInherits( self, name, access, virtual="" ) :
        self.__Inherits.append( [ name, access, virtual ] )
        if ( self.__Inherits[ -1 ][ 2 ] != "" ) :
            self.__Inherits[ -1 ][ 2 ] += " "
        return len( self.__Inherits )
    ## Allows to access the list of inheritance relations
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an array containing the inheritance relations.
    def getInherits( self ) :
        return self.__Inherits
    ## Allows to add a constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added.
    # @param[in] access "public", "protected" or "private".
    def _addConstructor( self, constructor, access ) :
        if ( access == "public" ) :
            self.__PublicConstr.append( constructor )
            return len( self.__PublicConstr )
        elif ( access == "protected" ) :
            self.__ProtectedConstr.append( constructor )
            return len( self.__ProtectedConstr )
        elif ( access == "private" ) :
            self.__PrivateConstr.append( constructor )
            return len( self.__PrivateConstr )
        else :
            return -1
    ## Allows to add a method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    # @param[in] access "public", "protected" or "private".
    def _addMethod( self, method, access ) :
        if ( access == "public" ) :
            self.__PublicMethod.append( method )
            return len( self.__PublicMethod )
        elif ( access == "protected" ) :
            self.__ProtectedMethod.append( method )
            return len( self.__ProtectedMethod )
        elif ( access == "private" ) :
            self.__PrivateMethod.append( method )
            return len( self.__PrivateMethod )
        else :
            return -1
    ## Allows to add a member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of member to be added.
    # @param[in] access "public", "protected" or "private".
    def _addMember( self, member, access ) :
        if ( access == "public" ) :
            self.__PublicMember.append( member )
            return len( self.__PublicMember )
        elif ( access == "protected" ) :
            self.__ProtectedMember.append( member )
            return len( self.__ProtectedMember )
        elif ( access == "private" ) :
            self.__PrivateMember.append( member )
            return len( self.__PrivateMember )
        else :
            return -1
    ## Allows to add a \e public constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added.
    #
    # @return number of \e public constructors.
    def addPublicConstructor( self, constructor ) :
        return self._addConstructor( constructor, "public" )
    ## Allows to access the list of \e public constructors.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e public constructors.
    def getPublicConstructors( self ) :
        return self.__PublicConstr
    ## Allows to add a \e public method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    #
    # @return the number of \e public methods.
    def addPublicMethod( self, method ) :
        return self._addMethod( method, "public" )
    ## Allows to access the list of \e public methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e public methods.
    def getPublicMethods( self ) :
        return self.__PublicMethod
    ## Allows to add a \e public member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of memeber to be added.
    #
    # @return the number of \e public members.
    def addPublicMember( self, member ) :
        return self._addMember( member, "public" )
    ## Allows to access the list of \e public members.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of public members.
    def getPublicMembers( self ) :
        return self.__ProtectedMember
    ## Allows to get the total number of \e public objects.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the sum of the lengths of PublicConstrutror,
    # PublicMethod and PublicMember.
    def getNbrPublicItems( self ) :
        result = len( self.__PublicConstr )
        result += len( self.__PublicMethod )
        result += len( self.__PublicMember )
        return result
    ## Allows to add a \e protected constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added.
    #
    # @return number of \e protected constructors.
    def addProtectedConstructor( self, constructor ) :
        return self._addConstructor( constructor, "protected" )
    ## Allows to access the list of \e protected constructors.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e protected constructors.
    def getProtectedConstructors( self ) :
        return self.__ProtectedConstr
    ## Allows to add a \e protected method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    #
    # @return the number of \e protected methods.
    def addProtectedMethod( self, method ) :
        return self._addMethod( method, "protected" )
    ## Allows to access the list of \e protected methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e protected methods.
    def getProtectedMethods( self ) :
        return self.__ProtectedMethod
    ## Allows to add a \e protected member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of memeber to be added.
    #
    # @return the number of \e protected members.
    def addProtectedMember( self, member ) :
        return self._addMember( member, "protected" )
    ## Allows to access the list of \e protected members.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of protected members.
    def getProtectedMembers( self ) :
        return self.__ProtectedMember
    ## Allows to get the total number of \e protected objects.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the sum of the lengths of ProtectedConstrutror,
    # ProtectedMethod and ProtectedMember.
    def getNbrProtectedItems( self ) :
        result = len( self.__ProtectedConstr )
        result += len( self.__ProtectedMethod )
        result += len( self.__ProtectedMember )
        return result
    ## Allows to add a \e private constructor.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] constructor instance of constructor to be added
    #
    # @return number of \e private constructors.
    def addPrivateConstructor( self, constructor ) :
        return self._addConstructor( constructor, "private" )
    ## Allows to access the list of \e private constructors.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e private constructors.
    def getPrivateConstructors( self ) :
        return self.__PrivateConstr
    ## Allows to add a \e private method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] method instance of method to be added.
    #
    # @return the number of \e private methods.
    def addPrivateMethod( self, method ) :
        return self._addMethod( method, "private" )
    ## Allows to access the list of \e private methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of \e private methods.
    def getPrivateMethods( self ) :
        return self.__PrivateMethod
    ## Allows to add a \e private member.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] member instance of memeber to be added.
    #
    # @return the number of \e private members.
    def addPrivateMember( self, member ) :
        return self._addMember( member, "private" )
    ## Allows to access the list of \e private members.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list of private members.
    def getPrivateMembers( self ) :
        return self.__PrivateMember
    ## Allows to get the total number of \e private objects.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the sum of the lengths of PrivateConstrutror,
    # PrivateMethod and PrivateMember.
    def getNbrPrivateItems( self ) :
        result = len( self.__PrivateConstr )
        result += len( self.__PrivateMethod )
        result += len( self.__PrivateMember )
        return result
    ## Allows to add a forward declaration.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string forward declaration string.
    #
    # @return the number of existing forward declarations.
    def addForwardDeclaration( self, string ) :
        self.__ForwardDeclaration.append( string )
        return len( self.__ForwardDeclaration )
    ## Allows to access the list of forward declarations.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an array containing the forward declarations.
    def getForwardDeclaration( self ) :
        return self.__ForwardDeclaration
    ## Allows to add a include in the header file. There are local and
    # distant inclusions, local means that the file is a header
    # written by the user, present somewhere in the compiled
    # code. Distant means that the header in present in /usr/include/
    # or equivalent.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string forward declaration string.
    # @param[in] local boolean value, \e True if include is local, \e
    # False if distant.
    #
    # @return the number of includes in the header file (for the given
    # local or distant category).
    def addHeaderInclude( self, string, local=False ) :
        if ( local ) :
            self.__LocalHeaderIncludes.append( string )
            return len( self.__LocalHeaderIncludes )
        else :
            self.__DistantHeaderIncludes.append( string )
            return len( self.__DistantHeaderIncludes )
    ## Allows to access the list of includes made in the header file
    # (local or distant).
    #
    # @param[in] self reference on the calling instance.
    # @param[in] local switch between local (\e True) and system
    # header files to be included (\e False).
    #
    # @return an array containing the list of includes.
    def getHeaderInclude( self, local=False ) :
        if ( local ) : return self.__LocalHeaderIncludes
        else : return self.__DistantHeaderIncludes
    ## Allows to add a include in the implementation file.
    # There are local and distant inclusions, local means that the
    # file is a implementation written by the user, present somewhere
    # in the source code. Distant means that the implementation in
    # present in /usr/include/ or equivalent.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string forward declaration string.
    # @param[in] local boolean value, \e True if include is local, \e
    # False if distant.
    #
    # @return the number of includes in the implementation file (for
    # the given local or distant category).
    def addImplementationInclude( self, string, local=False ) :
        if ( local ) :
            self.__LocalImplementationIncludes.append( string )
            return len( self.__LocalImplementationIncludes )
        else :
            self.__DistantImplementationIncludes.append( string )
            return len( self.__DistantImplementationIncludes )
    ## Allows to access the list of includes made in the implementation
    # file (local or distant).
    #
    # @param[in] self reference on the calling instance.
    # @param[in] local switch between local (\e True) and system
    # header files to be included (\e False).
    #
    # @return an array containing the list of includes.
    def getImplementationInclude( self, local=False ) :
        if ( local ) : return self.__LocalImplementationIncludes
        else : return self.__DistantImplementationIncludes
    ## Allows to add a "using namespace".
    #
    # @param[in] self reference on the calling instance.
    # @param[in] namespace name of the namespace to be added.
    # @param[in] header switch to add a "using namespace" in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return number of "using namespace" statements (either in the
    # header or in the implementation depending on the value of the
    # switch \c header).
    def addUsingNamespace( self, namespace, header ) :
        if ( header ) :
            self.__HeaderUsingNamespace.append( namespace )
            return len( self.__HeaderUsingNamespace )
        else :
            self.__ImplementationUsingNamespace.append( namespace )
            return len( self.__ImplementationUsingNamespace )
    ## Allows to get the "using namespace".
    #
    # @param[in] self reference on the calling instance.
    # @param[in] header switch to add a "using namespace" in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return an array containing the list of "using namespace"
    # statements (either in the header or in the implementation
    # depending on the value of the switch \c header).
    def getUsingNamespace( self, header ) :
        if ( header ) :
            return self.__HeaderUsingNamespace
        else :
            return self.__ImplementationUsingNamespace
    ## Allows to add an automatic method.
    # Before each insertion, it is checked whether there is already
    # such a method with another access specifier. If such a method is
    # found, nothing is added.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] what name of the item which will be added.
    # @param[in] access access specifier of the item.
    #
    # @return \e True if the addition could be made without problems,
    # \e False if a similar method is already present with another
    # access specifier.
    def addAutomaticMethod( self, what, access ) :
        if ( what in self.__AutomaticMethods.keys() ) :
            return False
        tmpDict = { what : access }
        self.__AutomaticMethods.update( tmpDict )
        return True
    ## Allows to get the dictionnary of automatic methods.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the dictionnary __AutomaticMethods
    def getAutomaticMethods( self ) :
        return self.__AutomaticMethods
    ## Allows to know whether at least one template method exists.
    # The method first looks in every list containing constructors or
    # methods and identifies the ones with template parameters. They
    # are added to a list, which length is tested at the end to know
    # if such methods (or constuctors) exist.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return \e True if at least one template method exists.
    def asTemplateMethods( self ) :
        self.__TemplateMethods = []
        for constructor in self.__PublicConstr :
            if ( constructor.isTemplate() ) :
                self.__TemplateMethods.append( constructor )
        for constructor in self.__ProtectedConstr :
            if ( constructor.isTemplate() ) :
                self.__TemplateMethods.append( constructor )
        for constructor in self.__PrivateConstr :
            if ( constructor.isTemplate() ) :
                self.__TemplateMethods.append( constructor )
        for method in self.__PublicMethod :
            if ( method.isTemplate() ) :
                self.__TemplateMethods.append( method )
        for method in self.__ProtectedMethod :
            if ( method.isTemplate() ) :
                self.__TemplateMethods.append( method )
        for method in self.__PrivateMethod :
            if ( method.isTemplate() ) :
                self.__TemplateMethods.append( method )
        return ( len( self.__TemplateMethods ) > 0 )
    ## Allows to get the list of template methods
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the list (array) of template methods.
    def getTemplateMethods( self ) :
        return self.__TemplateMethods
    ## Allows to access the list of template parameters.
    #
    # @param[in] self reference on calling instance.
    #
    # @return the list of template parameters.
    def getTemplateParameters( self ) :
        return self.__TemplateParameters
    ## Allows to add a template parameter to the template parameter
    # list.
    #
    # @param[in] self reference on calling instance.
    # @param[in] template template parameter to be added.
    #
    # @return nbr of template parameters.
    def addTemplateParameter( self, keyword, template ) :
        self.__TemplateParameters.append( [ keyword, template ] )
        return len( self.__TemplateParameters )
    ## Allows to know whether the class has at least one template
    ## parameter.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return \e True if at least one template parameter exists.
    def asTemplateParameters( self ) :
        return ( len( self.__TemplateParameters ) > 0 )
    ## Allows to know whether the class is a template or not.
    #
    # @param[in] self reference on calling instance.
    #
    # @return \e True if the class is a template.
    def isTemplate( self ) :
        return ( len( self.__TemplateParameters ) > 0 )
    ## Builds the "template< ... >" strings.
    # This is used to complete the implementation line of a function
    # (method or constructor) when the object is a template.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return "template< ... >" in case the object is a template.
    def getTemplateDeclaration( self ) :
        if ( not self.isTemplate() ) :
            return str()
        else :
            string = "template< "
            for param in self.getTemplateParameters() :
                string += param[ 0 ] + " " + param[ 1 ] + ", "
            string = string[:-2]
            string += " >\n"
            return string
    ## Builds the "< .. >" string which comes before the "::" when
    # writing the implementation.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return "< ... >" in case the object is a template.
    def getTemplateType( self ) :
        if ( not self.isTemplate() ) :
            return str()
        else :
            string = "< "
            for param in self.getTemplateParameters() :
                string += param[ 1 ] + ", "
            string = string[:-2]
            string += " >"
            return string            
    ## Allows to get the full object name, which comes before the "::"
    # when writing the implementation.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the name of the object, plus possible template
    # parameters.
    def getFullObjectTypeName( self ) :
        if ( not self.asTemplateParameters() ) :
            return self.getObjectName()
        else :
            return self.getObjectName() + self.getTemplateType()
    ## Allows to get the total number of members (without the static
    # ones).
    #
    # First gets the list of non-static members from
    # getNonStaticMembers.
    #
    # @param[in] self reference on the calling instance.
    #
    # @return the number of non-static members.
    def getNbrNonStaticMembers( self ) :
        return len( self.getNonStaticMembers() )
    ## Allows to get the list of \e all non-static members.
    # ones).
    #
    # @param[in] self reference on the calling instance.
    #
    # @return an array containing the non-static members.
    def getNonStaticMembers( self ) :
        results = []
        for member in self.__PublicMember :
            if ( not member.getStatic() ) :
                results.append( member.getName() )
        for member in self.__ProtectedMember :
            if ( not member.getStatic() ) :
                results.append( member.getName() )
        for member in self.__PrivateMember :
            if ( not member.getStatic() ) :
                results.append( member.getName() )
        return results
    ## Allows to print the instance in its header file.

    # The author and data comments are written even if the comment was
    # disabled for the object. If a namespace was specified it is
    # written before the object declaration and the identation will be
    # modified according to this. The order in which the various
    # elements of the object are written is this:
    # - the public constructors,
    # - the public methods,
    # - the public members,
    # - the protected constructors,
    # - the protected methods,
    # - the protected members,
    # - the private constructors,
    # - the private methods,
    # - the private members.
    #
    # Then, if the object has template methods, their implementation
    # will be put after the object declaration. If the object is a
    # template, then all the methods will be put after the object
    # declaration with the \e same order as in the object prototype.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] objectType name of the object, i.e. "class" or
    # "struct".
    # @param[in] stream output stream used to print the data.
    # @param[in] comments toggles on/off comments printing
    def writeHeader( self, stream, comments ) :
        prefix = ""
        if ( self.getNamespace() != "" ) :
            stream.write( "namespace " + self.getNamespace() + "\n{\n" )
            prefix = " " * 2
        stream.write( prefix + "/**\n" )
        for author in self.getAuthors() :
            stream.write( prefix + " * @author "+ author + "\n" )
        stream.write( prefix + " * @date " + self.getDate()  + "\n" )
        stream.write( prefix + " */"  + "\n" )
        line = str( "" )
        if ( self.isTemplate() ) :
            line = self.getTemplateDeclaration()
            stream.write( prefix + line )
        line = self.getObjectType() + " " + self.getObjectName()
        for iMother in range( len( self.__Inherits ) ) :
            mother = self.__Inherits[ iMother ]
            if ( iMother == 0 ) :
                line += " : "
            else :
                line += ", "
            line += mother[ 1 ] + " " + mother[ 2 ] + mother[ 0 ]
        stream.write( prefix + line  + "\n" )
        stream.write( prefix + "{\n" + prefix + "public:\n" )
        prefix += " " * 2
        for displayItem in self.__PublicConstr :
            self._writeItemHeader( stream, displayItem, comments, prefix )
        for displayItem in self.__PublicMethod :
            self._writeItemHeader( stream, displayItem, comments, prefix )
        for displayItem in self.__PublicMember :
            self._writeItemHeader( stream, displayItem, comments, prefix )
        if ( self.getNbrProtectedItems() > 0 ) :
            stream.write( prefix + "protected:\n" )
            for displayItem in self.__ProtectedConstr :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__ProtectedMethod :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__ProtectedMember :
                self._writeItemHeader( stream, displayItem, comments, prefix )
        if ( self.getNbrPrivateItems() > 0 ) :
            stream.write( prefix + "private:\n" )
            for displayItem in self.__PrivateConstr :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__PrivateMethod :
                self._writeItemHeader( stream, displayItem, comments, prefix )
            for displayItem in self.__PrivateMember :
                self._writeItemHeader( stream, displayItem, comments, prefix )

        if ( self.getNamespace() != "" ) :
            prefix = " " * 2
        else :
            prefix = ""

        stream.write( prefix + "};\n" )

        if ( self.getNamespace() != "" ) :
            prefix = " " * 2
        else :
            prefix = ""

        if ( self.asTemplateMethods() ) :
            stream.write( "\n" )
            templateMethods = self.getTemplateMethods()
            for displayItem in templateMethods :
                self._writeItemImplementation( stream, displayItem, \
                                                   prefix, True )
                strLines = self._getFunctionBody( displayItem, True )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
        if ( self.isTemplate() ) :
            stream.write( "\n" )
            for displayItem in self.__PublicConstr :
                self._writeItemImplementation( stream, displayItem, \
                                                   prefix, True )
                strLines = self._getFunctionBody( displayItem, True )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
            for displayItem in self.__PublicMethod :
                self._writeItemImplementation( stream, displayItem, \
                                                   prefix, True )
                strLines = self._getFunctionBody( displayItem, True )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
            if ( self.getNbrProtectedItems() > 0 ) :
                for displayItem in self.__ProtectedConstr :
                    self._writeItemImplementation( stream, displayItem, \
                                                       prefix, True )
                    strLines = self._getFunctionBody( displayItem, True )
                    strLines = strLines.replace( "\n", "\n" + prefix )
                    stream.write( prefix + strLines + "\n\n" )
                for displayItem in self.__ProtectedMethod :
                    self._writeItemImplementation( stream, displayItem, \
                                                       prefix, True )
                    strLines = self._getFunctionBody( displayItem, True )
                    strLines = strLines.replace( "\n", "\n" + prefix )
                    stream.write( prefix + strLines + "\n\n" )
            if ( self.getNbrPrivateItems() > 0 ) :
                for displayItem in self.__PrivateConstr :
                    self._writeItemImplementation( stream, displayItem, \
                                                       prefix, True )
                    strLines = self._getFunctionBody( displayItem, True )
                    strLines = strLines.replace( "\n", "\n" + prefix )
                    stream.write( prefix + strLines + "\n\n" )
                for displayItem in self.__PrivateMethod :
                    self._writeItemImplementation( stream, displayItem, \
                                                       prefix, True )
                    strLines = self._getFunctionBody( displayItem, True )
                    strLines = strLines.replace( "\n", "\n" + prefix )
                    stream.write( prefix + strLines + "\n\n" )
            
        if ( self.getNamespace() != "" ) :
            stream.write( "}" )
    ## Helper function to avoid code duplication in the writeHeader
    ## method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] item item for which the print out has to be done.
    # @param[in] comments switches comments production
    # @param[in] prefix string prepended to each line (a couple of
    # white spaces).
    # @param[in] header switches on writing the header file.
    def _writeItemHeader( self, stream, item, comments, prefix, \
                              header = True ) :        
        strLine, strComment = ( item.producePrototype( header ), \
                                    item.produceComment() )
        if ( comments and prefix != "" ) :
            strComment = strComment.replace( "\n", "\n" + prefix )
            stream.write( prefix +  strComment + "\n" )
        elif ( comments ) :
            stream.write( strComment + "\n" )
        strLine = strLine.replace( "\n", "\n" + prefix )
        strLine = self._removeNamespace( strLine, True )
        stream.write( prefix + strLine + "\n" )
    ## Allows to print the instance in its implementation file.

    # If the object is a template, then nothing will be written at all
    # in the implementation file. If the object lives in a namespace,
    # a "using namespace" statuement is added. Then all constructors
    # and methods have their implementation written, in the \e same
    # order as in the object prototype.
    #
    # @param[in] self reference on the calling instance. 
    # @param[in] stream output stream used to print the data.
    def writeImplementation( self, stream ) :

        if ( self.isTemplate() ) :
            return

        if ( self.getNamespace() != "" ) :
            stream.write( "using namespace " + self.getNamespace() + ";\n\n" )

        prefix = ""
        
        for displayItem in self.__PublicConstr :
            if ( _FBaseRepresentation.isTemplate( displayItem ) ) : continue
            self._writeItemImplementation( stream, displayItem, prefix )
            strLines = self._getFunctionBody( displayItem, False )
            strLines = strLines.replace( "\n", "\n" + prefix )
            stream.write( prefix + strLines + "\n\n" )
        for displayItem in self.__PublicMethod :
            if ( _FBaseRepresentation.isTemplate( displayItem ) ) : continue
            self._writeItemImplementation( stream, displayItem, prefix )
            strLines = self._getFunctionBody( displayItem, False )
            strLines = strLines.replace( "\n", "\n" + prefix )
            stream.write( prefix + strLines + "\n\n" )
        for displayItem in self.__PublicMember :
            self._writeItemImplementation( stream, displayItem, prefix )
        if ( self.getNbrProtectedItems() > 0 ) :
            for displayItem in self.__ProtectedConstr :
                if ( _FBaseRepresentation.isTemplate( displayItem ) ) : continue
                self._writeItemImplementation( stream, displayItem, prefix )
                strLines = self._getFunctionBody( displayItem, False )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
            for displayItem in self.__ProtectedMethod :
                if ( _FBaseRepresentation.isTemplate( displayItem ) ) : continue
                self._writeItemImplementation( stream, displayItem, prefix )
                strLines = self._getFunctionBody( displayItem, False )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
            for displayItem in self.__ProtectedMember :
                self._writeItemImplementation( stream, displayItem, prefix )
        if ( self.getNbrPrivateItems() > 0 ) :
            for displayItem in self.__PrivateConstr :
                if ( _FBaseRepresentation.isTemplate( displayItem ) ) : continue
                self._writeItemImplementation( stream, displayItem, prefix )
                strLines = self._getFunctionBody( displayItem, False )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
            for displayItem in self.__PrivateMethod :
                if ( _FBaseRepresentation.isTemplate( displayItem ) ) : continue
                self._writeItemImplementation( stream, displayItem, prefix )
                strLines = self._getFunctionBody( displayItem, False )
                strLines = strLines.replace( "\n", "\n" + prefix )
                stream.write( prefix + strLines + "\n\n" )
            for displayItem in self.__PrivateMember :
                self._writeItemImplementation( stream, displayItem, prefix )
    ## Helper function to avoid code duplication in the
    # writeImplementation method.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] item item for which the print out has to be done.
    # @param[in] prefix string prepended to each line (a couple of
    # white spaces).
    # @param[in] header switches on writing the header file.
    def _writeItemImplementation( self, stream, item, prefix, header = False ) :
        strLine = item.produceImplementation( header )
        strLine = strLine.format( self.getTemplateDeclaration(), \
                                      self.getFullObjectTypeName() )
        strLine = strLine.replace( "\n", "\n" + prefix )
        stream.write( prefix + self._removeNamespace( strLine, header ) + "\n" )
    ## Formats the function bodies, i.e. retrieves the body and then
    # removes the namespaces according to the list of used namespaces.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] function instance of function for which the body is
    # wanted.
    # @param[in] header switch to add a "using namespace" in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return the body of the function, with used namespace removed.
    def _getFunctionBody( self, function, header ) :
        string = self._removeNamespace( function.getBody(), header )

        return string
    ## Function which removes any mention of "namespace::" for each
    # namespace used.
    #
    # @param[in] self reference on the calling instance.
    # @param[in] string character string to be processed.
    # @param[in] header switch to add a "using namespace" in the
    # header file (if \e True) or in the implementation (\e False ).
    #
    # @return the character string \c string with the "namespace::"
    # removed.
    def _removeNamespace( self, string, header ):
        listOfNamespaces = self.getUsingNamespace( header )

        for namespace in listOfNamespaces :
            toDelete = namespace + "::"
            string = string.replace( toDelete, "" )
        
        return string

## Class representing a C++ class. A C++ class is defined by its name,
# the namespace it belongs to, a list of constructors, methods and
# members. Additional information are also provided, like the name of
# the author and the date of creation.
#
# @author Johan "Solo" Luisier
# @date October 2011
class ClassRepresentation( _ObjectBaseRepresentation ) :
    ## Constructor
    # Initialises the members. All names are set to an empty string
    # and the lists are set to empty arrays.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        _ObjectBaseRepresentation.__init__( self )
        self.setObjectType( "class" )
        
## Class representing a C++ structure. A C++ structure is defined by
# its name, the namespace it belongs to, a list of constructors,
# methods and members. Additional information are also provided, like
# the name of the author and the date of creation.
#
# @author Johan "Solo" Luisier
# @date February 2012
class StructureRepresentation( _ObjectBaseRepresentation ) :
    ## Constructor
    # Initialises the members. All names are set to an empty string
    # and the lists are set to empty arrays.
    #
    # @param[in] self reference on the calling instance.
    def __init__( self ) :
        _ObjectBaseRepresentation.__init__( self )
        self.setObjectType( "struct" )
        
